﻿// -----------------------------------------------------------------------
// <copyright file="GeneradorDeSelect.cs" company="Hexacta S.A.">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace generador
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using gudusoft.gsqlparser;
    using System.Collections;

    /// <summary>
    /// TODO: limitado, ver de no setear los ID, lo mismo deberia ver para las otras queryes (select)
    /// </summary>
    public static class GeneradorDeUpdate
    {
        //limitaciones hasta el momento: join 1 tabla, no uso funciones como SELECT sum(field1) FROM, 
        //ORDER By no tiene, las expresiones solo con AND y no chequeo tipos de las columnas solo aplico valores enteros.., Ademas es limitada la cantidad
        public static InfoDeLaQuery GenerarUpdate(DataSet ds, Dictionary<string, int> diccionario_Tabla_Cantidad_de_Registros)
        {
            TUpdateSqlStatement statement = new TUpdateSqlStatement(TDbVendor.DbVMssql);
            statement.IsParsed = true;

            InfoDeLaQuery info = new InfoDeLaQuery();
            info.Query = statement;

            //TLzField column = null;

            DataTable tabla_elegida = Utiles.ElegirTablaAlAzar(ds);
            IList<DataColumn> columnas_posibles;
           
                columnas_posibles = Utiles.ConvertirAIListFromDataColumnCollection(tabla_elegida.Columns);

            IList<DataColumn> campos_elegidos = ElegirCamposYValoresUpdate(statement, columnas_posibles);

            TLzJoin join1 = new TLzJoin(statement);
            join1.JoinTable = new TLzTable(statement);
            join1.JoinTable.TableName = tabla_elegida.TableName;
            statement.UpdateTables.Add(join1);

            info.RowsExamined = diccionario_Tabla_Cantidad_de_Registros[tabla_elegida.TableName];


            if (Utiles.RandomEntreTrueYFalse())
            {
                AgregarWhere(statement, columnas_posibles);
                //SI TIENE WHERE NO SE BIEN CUANTOS REGISTRO RETORNARA, ENTONCES RANDOM DE LOS QUE EXAMINA
                info.RowsSent = Utiles.random.Next(info.RowsExamined); 
            }
            else 
            {
                info.RowsSent = info.RowsExamined; 
            }

            //????????????Tiene q ser igual al tiempo de la query??????????????????????????
            info.LockTime = Utiles.random.Next(0,Constantes.TiempoMaximoLockeoDeTabla);

            return info;
        }


        private static void AgregarWhere(TUpdateSqlStatement statement, IList<DataColumn> columnas_posibles)
        {
            TLzCustomExpression where = new TLzCustomExpression(statement);

            int cantidad_binarias = DameAlAzarCantidadExpresionesBinarias();
            where = Utiles.GenerarExpresionWhereRecursivamente(columnas_posibles, where, cantidad_binarias);

            statement.WhereClauseText = where.AsText;
        }

        private static int DameAlAzarCantidadExpresionesBinarias()
        {
            return Utiles.random.Next(4);
        }
       

        private static IList<DataColumn> ElegirCamposYValoresUpdate(TUpdateSqlStatement statement, IList<DataColumn> columnas)
        {
            TLzField field1;
            IList<DataColumn> campos_elegidos = new List<DataColumn>();

            int cantidad_de_campos = Utiles.random.Next(1,Constantes.CantidadMaximaDeCampos);
             
            IList<DataColumn> posibles_campos = new List<DataColumn>();
            foreach (DataColumn columna in columnas)
            {
                posibles_campos.Add(columna);
            }
            //elijo un campo posible, lo pongo en la query y luego lo saco de los posibles campos futuros a elegir
            int cantidad_de_campos_definitiva = Math.Min(cantidad_de_campos, posibles_campos.Count);//no pedir mas campos de los que tengo

            for (int i = 0; i < cantidad_de_campos_definitiva; i++)
            {
                DataColumn columna_elegida = Utiles.ElegirElementoAlAzar<DataColumn>(posibles_campos);

                field1 = new TLzField(statement);
                field1.FieldExpr = new TLzCustomExpression(statement);
                field1.AsText = columna_elegida.ColumnName + " = " + Utiles.random.Next(100);
                statement.Fields.Add(field1);

                campos_elegidos.Add(columna_elegida);
                posibles_campos.Remove(columna_elegida);
            }

            return campos_elegidos;
        }
    }
}


 ;